Lab 3 – Counting System Calls
In this lab you will learn about the /proc file system and how to install new /proc modules into the running Linux kernel.  The /proc filesystem is a virtual filesystem that doesn't contain real files, but instead contains runtime information about the system.  Many utility commands are just thin programs that display the contents of /proc files with minimal reformatting.
NOTE: If DevBox doesn't let you start the GUI, look for alternate instructions in orange throughout the lab instructions.
Take a few minutes, and look at this page about /proc (Links to an external site.)
Let's get starting with looking around:
Boot DevBox, but instead of logging in, type <CTRL>-ALT-F3 at the login screen. This will drop you into a terminal window. Login using the student id. Once there, make sure you can successfully do:  "ping hackbox". Then proceed with the lab:
•	On DevBox: Start a terminal window and change directory to /proc, and then list the files
$ cd /proc
$ ls -l
What do you notice about the size of the files?  What about the names of the files?
•	On DevBox: Execute the following commands and look at the results:
$ cat /proc/uptime
$ cat /proc/loadavg
$ uptime
The /proc/uptime file contains information about how long the machine has been running. The first of the two numbers is the time in seconds since the kernel started. The /proc/loadavg file gives the CPU and I/O utilization over the last 1-minute, 5-minute and 10-minute periods. The other numbers are the number of currently running processes, the total number of processes, and the last process id used.

Compare the information from printing out the /proc files to the results of the third command, uptime
•	On DevBox: Use “ps lax” to list all the processes running and find the process ID (PID) of a running process. The PID is the third column. Pick a process that looks interesting to you. Next use the “ps -p” command to examine information about that process.
$ ps lax | more
$ ps -p <the pid you chose>
Now, examine information about this process in the /proc filesystem. First change in the /proc/<pid> directory (where “<pid>” is the process ID of the process you are interested in examining).
$ cd <pid>
$ cat cmdline
$ cat limits
$ cat status
Poke around and try doing “cat <filename>” for a few more files in the /proc filesystem. Can you figure out what they are? These files all contain information about the running process.
Next, you are going to download and install a new module that creates a /proc file. The first is an already written sample module. You will then write one that keeps track of the number of each system call that is made. First the sample:
If you can't start the GUI, you can't bring up a browser window. Instead, download the file mentioned below to your Windows machine, and then use scp to move the file to DevBox.  The ip address for your DevBox will be 192.168.56.101 most likely. You can confirm this by performing the DevBox command: "ifconfig" and then look for the ip address associated with the eth1 listing. This web page (Links to an external site) explains how to use scp if you do not already know how to do so. The target of the scp will be student@192.168.56.101:~/cis-4020. Then, on DevBox, "cd cis-4020" and "unzip procfile-skeleton". Then, follow the instructions below.
•	On DevBox: Bring up a browser window and go to Canvas and download "procfile-skeleton.zip". This is a zip file, so once you download it, double click on the downloaded file, and extract it into the directory student/cis-4020. You'll then have a directory named procfile-skeleton. 
$ cd /home/student/cis-4020/procfile-skeleton
$ make
This will build the new module. Once it is built, you should have a file hello_procfile.ko.  This is the kernel module file. Next, move hello_procfile.ko to HackBox -- make sure you have a snapshot first!
$ scp hello_procfile.ko student@hackbox: 
•	On HackBox: Log in and verify that the file exists. Then do:
$ sudo insmod hello_procfile.ko
To install the module. 
•	On DevBox: Bring up hello_procfile.c in vim, nano, gedit, and look at the source code. Can you figure out what the module does (in a big picture sense)? Can you figure out what the name of the /proc file will be?  Can you find the kernel messages you can use to tell if it installed properly?
•	On HackBox: Use the dmesg command to see if the module installed properly into your running kernel. Also, look in the /proc file system, and see if you can figure out which entry is your new module. Execute 'cat <module>' and look at the output. Is the module working properly? What does it do?
Once you have the sample /proc module installed and working, look more closely at its code in vim. 
Also spend some time reading: Driver porting: The seq_file interface. (Links to an external site)
The next step is to create a /proc module of your own that will count all the system calls that are being made by the kernel.  We not only want to count the calls, but also have a /proc module that will display the information in a reasonable way.  I'll walk you through the edit necessary to count the system calls, and then you'll start with the skeleton procfile and change it to display the system call information.
Instrumenting the system call counting
To keep track of every system call made, we need two pieces: an array to hold onto the counts per call, and then a change to the kernel code to actually increment the appropriate space in the array when a system call is made. As mentioned last week, the name of the array to hold the call will be call_counters.
•	On DevBox: Add the definition:
unsigned long call_counters[550]; // Why 550?
EXPORT_SYMBOL( call_counters );
to the file arch/x86/entry/common.c. Add these lines somewhat near the top -- after the includes and defines but before the functions would work.
The first line defines the array that will hold the counts of the system calls.  The second line makes the symbol visible to installable kernel modules such as the module we will be writing.
Whenever modifying kernel files, it is always a good idea to make a copy of the file (e.g., with a command such as: cp common.c common.c.orig) before you edit it.
•	On DevBox: The first function in common.c is do_syscall_x64. One parameter of this function is the system call number, nr. Add a line of code to that function immediately above where the system call is actually made that increments the appropriate element of the call_counters array
•	On DevBox: Go back up to the top-level directory, and compile the kernel, transfer it over to HackBox, and reboot HackBox to make sure the kernel is still working. Be sure you have a snapshot of HackBox, just in case. If you don't remember how to compile the kernel, refer to the instructions titled "How to build a HackBox kernel" in Canvas.
•	On DevBox: Now that you have a new kernel on HackBox, you have to write a syscall_counters /proc file module, similar to the hello_procfile module we examined above.  If you haven't already, make a copy of the hello_procfile directory:
$ cd cis-4020
$ mkdir call_counters
$ cp procfile-skeleton/* call_counters
$ cd call_counters
At this point, you can perform a “make clean” to get rid of any extra files in your call_counters directory.  Make the necessary changes in the files to create a syscall_counters.c file that will use the call_counters and print out the results. The output should look something like this:

  0: 44479
  1: 32412
....

That is, the system call number followed by the count of how many times that system call was made.

HINT:   %lu is how you print an unsigned long in a printf.  

Once you have completed your coding, edit the Kbuild file and Makefile as needed, and build your new /proc module. Use scp to transfer the ko file to hackbox as before.
•	On HackBox: Use insmod to install your module, and then perform the command:
$ less /proc/syscall_counters
and examine the results. Which system calls have the biggest numbers? You can look at the file arch/x86/include/generated/uapi/asm/unistd_64.h to find the system call numbers.
Once you have verified that you are getting proper results, please submit the following:
•	The source code of your module.
•	A copy of the results “displayed” by the syscall_counters proc file. To capture the output, you can do: "cat /proc/syscall_counters >& count.out". This should create a file named count.out in the current directory.
You can use scp in reverse to retrieve the files.  From your windows machine:
scp student@192.168.56.101:~/cis-4020/call_counters/call_counters.c .
scp student@192.168.56.101:~/cis-4020/call_counters/counts.out .